/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package pl.droidsonroids.gif.gifsample;

import static junit.framework.TestCase.assertNotNull;
import static org.junit.Assert.assertEquals;

import ohos.aafwk.ability.DataAbilityHelper;
import ohos.aafwk.ability.DataAbilityRemoteException;
import ohos.aafwk.ability.delegation.AbilityDelegatorRegistry;
import ohos.app.Context;
import ohos.global.resource.RawFileDescriptor;
import ohos.global.resource.RawFileEntry;
import ohos.global.resource.Resource;
import ohos.utils.net.Uri;
import pl.droidsonroids.gif.GifDrawable;

import org.junit.Before;
import org.junit.Test;

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.RandomAccessFile;
import java.nio.ByteBuffer;

/**
 * GifElementTest
 */
public class GifElementTest {
    private Context mContext;

    /**
     * setUp
     */
    @Before
    public void setUp() {
        mContext = AbilityDelegatorRegistry.getAbilityDelegator().getAppContext();
    }

    /**
     * createInstanceWithByteArray
     * @throws IOException exception
     */
    @Test
    public void createInstanceWithByteArray() throws IOException {
        byte[] mByteArray = getByteArrayFromRawFile("entry/resources/rawfile/anim_flag_chile.gif");
        GifDrawable element = new GifDrawable(mByteArray);
        assertNotNull(element);
    }

    /**
     * createInstanceWithByteBuffer
     * @throws IOException exception
     */
    @Test
    public void createInstanceWithByteBuffer() throws IOException {
        byte[] mByteArr = getByteArrayFromRawFile("entry/resources/rawfile/anim_flag_hungary.gif");
        ByteBuffer mByteBuffer = ByteBuffer.allocateDirect(mByteArr.length);
        mByteBuffer.put(mByteArr);
        GifDrawable element = new GifDrawable(mByteBuffer);
        assertNotNull(element);
    }

    /**
     * createInstanceWithUri
     * @throws IOException exception
     * @throws DataAbilityRemoteException exception
     */
    @Test
    public void createInstanceWithUri() throws IOException, DataAbilityRemoteException {
        File gifFile = getFileFromRawFile("entry/resources/rawfile/anim_flag_chile.gif", "chile.gif");
        Uri uri = Uri.parse("file:///" + gifFile.getAbsolutePath());
        GifDrawable element = new GifDrawable(DataAbilityHelper.creator(mContext, uri), uri);
        assertNotNull(element);
    }

    /**
     * createInstanceWithBufferedInputStream
     * @throws IOException exception
     */
    @Test
    public void createInstanceWithBufferedInputStream() throws IOException {
        RawFileEntry rawFileEntry = mContext.getResourceManager()
            .getRawFileEntry("entry/resources/rawfile/anim_flag_iceland.gif");
        InputStream resource = rawFileEntry.openRawFile();
        BufferedInputStream bufferedInputStream = new BufferedInputStream(resource);
        GifDrawable element = new GifDrawable(bufferedInputStream);
        assertNotNull(element);
    }

    /**
     * createInstanceWithFile
     * @throws IOException exception
     */
    @Test
    public void createInstanceWithFile() throws IOException {
        File file = getFileFromRawFile("entry/resources/rawfile/anim_flag_hungary.gif", "hungary.gif");
        GifDrawable element = new GifDrawable(file);
        assertNotNull(element);
    }

    /**
     * createInstanceWithFileDescriptor
     * @throws IOException exception
     */
    @Test
    public void createInstanceWithFileDescriptor() throws IOException {
        File fileRandom = getFileFromRawFile("entry/resources/rawfile/anim_flag_england.gif", "england.gif");
        FileDescriptor fd = new RandomAccessFile(fileRandom, "r").getFD();
        GifDrawable element = null;
        if (fd != null) {
            element = new GifDrawable(fd);
        }
        assertNotNull(element);
    }

    /**
     * createInstanceWithRawFileDescriptor
     * @throws IOException exception
     */
    @Test
    public void createInstanceWithRawFileDescriptor() throws IOException {
        RawFileDescriptor rawFileDescriptor = mContext.getResourceManager()
            .getRawFileEntry("entry/resources/rawfile/anim_flag_iceland.gif").openRawFileDescriptor();
        GifDrawable element = new GifDrawable(rawFileDescriptor);
        assertNotNull(element);
    }

    private File getFileFromRawFile(String string, String filename) {
        byte[] buf = null;
        try {
            File file = new File(mContext.getCacheDir(), filename);
            RawFileEntry rawFileEntry = mContext.getResourceManager().getRawFileEntry(string);
            Resource resource = rawFileEntry.openRawFile();
            buf = new byte[(int) rawFileEntry.openRawFileDescriptor().getFileSize()];
            int bytesRead = resource.read(buf);
            if (bytesRead != buf.length) {
                throw new IOException("Asset read failed");
            }
            FileOutputStream output = new FileOutputStream(file);
            output.write(buf, 0, bytesRead);
            output.close();
            return file;
        } catch (IOException ex) {
            throw new IllegalStateException(ex);
        }
    }

    private byte[] getByteArrayFromRawFile(String string) {
        byte[] buf = null;
        try {
            RawFileEntry rawFileEntry = mContext.getResourceManager().getRawFileEntry(string);
            Resource resource = rawFileEntry.openRawFile();
            buf = new byte[(int) rawFileEntry.openRawFileDescriptor().getFileSize()];
            int bytesRead = resource.read(buf);
            if (bytesRead != buf.length) {
                throw new IOException("Asset read failed");
            }
            return buf;
        } catch (IOException e) {
            // ignore
        }
        return buf;
    }

}